import time
from typing import Dict, Any, List
from src.utils.logger import get_logger
from src.utils.timehelper import TimeHelper
from src.utils.redis import RedisHelper

logger = get_logger("capcut")


class TaskStatusManager:
    """任务状态管理器，负责任务状态的CRUD操作"""
    # 任务状态常量
    STATUS_QUEUED = 'queued'  # 任务已加入队列
    STATUS_PROCESSING = 'processing'  # 任务处理中
    STATUS_SUCCESS = 'success'  # 任务处理成功
    STATUS_FAILED = 'failed'  # 任务处理失败

    def __init__(self):
        """初始化任务状态管理器，使用RedisHelper全局实例"""
        # 确保RedisHelper已初始化
        if not RedisHelper._global_instance:
            RedisHelper.initialize()

    def init_task_status(self, task_id: str, draft_id: str) -> None:
        """
        初始化任务状态

        Args:
            task_id: 任务唯一ID
            draft_id: 剪映草稿ID
        """
        try:
            # 初始化任务基本信息
            RedisHelper.hset(
                f"render_task:{task_id}",
                mapping={
                    'status': self.STATUS_QUEUED,
                    'draft_id': draft_id,
                    'oss_url': '',
                    'error': '',
                    'progress': '0',
                    'message': '任务已加入队列',
                    'created_at': TimeHelper.milliseconds(),
                    'updated_at': TimeHelper.milliseconds()
                }
            )

            # 建立草稿ID与任务ID的关联
            RedisHelper.sadd(f"draft:{draft_id}:tasks", task_id)
            logger.info(f"任务状态初始化成功: task_id={task_id}, draft_id={draft_id}")
        except Exception as e:
            logger.error(f"任务状态初始化失败: {str(e)}")
            raise

    def update_task_status(self, task_id: str, **kwargs) -> None:
        """
        更新任务状态

        Args:
            task_id: 任务唯一ID
            **kwargs: 要更新的状态字段，如status, progress, message等
        """
        try:
            # 添加更新时间戳
            kwargs['updated_at'] = TimeHelper.milliseconds()

            # 更新任务状态
            RedisHelper.hset(
                f"render_task:{task_id}",
                mapping=kwargs
            )

            # 记录关键状态变更
            if 'status' in kwargs:
                logger.info(f"任务状态变更: task_id={task_id}, status={kwargs['status']}")
            elif 'progress' in kwargs:
                logger.info(f"任务进度更新: task_id={task_id}, progress={kwargs['progress']}%")
        except Exception as e:
            logger.error(f"任务状态更新失败: {str(e)}")
            raise

    def get_task_status(self, task_id: str) -> Dict[str, Any]:
        """
        查询任务状态

        Args:
            task_id: 任务唯一ID

        Returns:
            包含任务状态信息的字典
        """
        try:
            # 获取任务状态数据
            task_data = RedisHelper.hgetall(f"render_task:{task_id}")
            if not task_data:
                return {'error': '任务不存在', 'status': ''}

            # 转换数值类型
            if 'progress' in task_data:
                try:
                    task_data['progress'] = float(task_data['progress'])
                except ValueError:
                    task_data['progress'] = 0.0

            if 'created_at' in task_data:
                try:
                    task_data['created_at'] = int(task_data['created_at'])
                except ValueError:
                    pass

            if 'updated_at' in task_data:
                try:
                    task_data['updated_at'] = int(task_data['updated_at'])
                except ValueError:
                    pass

            return task_data
        except Exception as e:
            logger.error(f"任务状态查询失败: {str(e)}")
            return {'error': f"查询失败: {str(e)}", 'status': ''}

    def get_draft_tasks(self, draft_id: str) -> list:
        """
        获取指定草稿ID关联的所有任务ID

        Args:
            draft_id: 剪映草稿ID

        Returns:
            任务ID列表
        """
        try:
            return RedisHelper.smembers(f"draft:{draft_id}:tasks")
        except Exception as e:
            logger.error(f"获取草稿任务列表失败: {str(e)}")
            return []

    def get_draft_tasks_all(self, draft_id: str) -> List[Dict[str, Any]]:
        """
        获取指定草稿ID关联的所有任务状态信息

        Args:
            draft_id: 剪映草稿ID

        Returns:
            任务状态信息列表，每个元素是一个任务的状态字典，字段顺序一致
        """
        try:
            # 获取所有关联的任务ID
            task_ids = RedisHelper.smembers(f"draft:{draft_id}:tasks")
            if not task_ids:
                return []

            # 使用管道批量获取所有任务状态
            with RedisHelper.pipeline() as pipe:
                for task_id in task_ids:
                    pipe.hgetall(f"render_task:{task_id}")
                results = pipe.execute()

            # 定义字段顺序
            field_order = [
                'task_id', 'status', 'draft_id', 'oss_url', 'error',
                'progress', 'message', 'created_at', 'updated_at'
            ]

            # 处理结果
            task_status_list = []
            for task_id, task_data in zip(task_ids, results):
                if not task_data:
                    # 任务不存在的情况 - 按照字段顺序创建字典
                    ordered_data = {field: '' for field in field_order}
                    ordered_data.update({
                        'task_id': task_id,
                        'error': '任务不存在',
                        'status': ''
                    })
                    task_status_list.append(ordered_data)
                    continue

                # 转换字节键和值为字符串
                decoded_data = {}
                for k, v in task_data.items():
                    decoded_data[k.decode('utf-8')] = v.decode('utf-8') if v is not None else None

                # 转换数值类型
                if 'progress' in decoded_data:
                    try:
                        decoded_data['progress'] = float(decoded_data['progress'])
                    except ValueError:
                        decoded_data['progress'] = 0.0

                if 'created_at' in decoded_data:
                    try:
                        decoded_data['created_at'] = int(decoded_data['created_at'])
                    except ValueError:
                        pass

                if 'updated_at' in decoded_data:
                    try:
                        decoded_data['updated_at'] = int(decoded_data['updated_at'])
                    except ValueError:
                        pass

                # 添加任务ID到返回结果中
                decoded_data['task_id'] = task_id

                # 按照预定义的字段顺序创建有序字典
                ordered_data = {}
                for field in field_order:
                    ordered_data[field] = decoded_data.get(field, '')

                task_status_list.append(ordered_data)

            return task_status_list
        except Exception as e:
            logger.error(f"获取草稿任务列表失败: {str(e)}")
            return []